#include "../../mqserver/message.hpp"
#include <gtest/gtest.h>

MyRabbitMQ::MessageManager::ptr hosts;

class MessageTest : public testing::Environment
{
public:
    // 初始化
    virtual void SetUp() override
    {
        hosts = std::make_shared<MyRabbitMQ::MessageManager>("./");
    }

    virtual void TearDown() override
    {
        // 清理交换机测试
        // msgs->clear();
        std::cout << "执行真正数据库清理操作" << std::endl;
    }
};
// 声明消息管理单元测试
TEST(MessageTest, declare_test)
{
    hosts->declareQueueMessageManager("queue-1");
    hosts->declareQueueMessageManager("queue-2");
    hosts->declareQueueMessageManager("queue-3");
    hosts->declareQueueMessageManager("queue-4");
    hosts->declareQueueMessageManager("queue-5");
    hosts->declareQueueMessageManager("queue-6");
    hosts->declareQueueMessageManager("queue-7");
    hosts->declareQueueMessageManager("queue-8");
    hosts->declareQueueMessageManager("queue-9");
    hosts->declareQueueMessageManager("queue-0");
}

// 删除消息管理单元测试
TEST(MessageTest, delete_test)
{
    hosts->deleteQueueMessageManager("queue-6");
    hosts->deleteQueueMessageManager("queue-7");
}

// 向队列添加消息测试
TEST(MessageTest, insert_test)
{
    // 测试 插入不存在队列情况
    protoMQ::BaseProperties base1;
    protoMQ::BaseProperties base2;
    protoMQ::BaseProperties base3;
    protoMQ::BaseProperties base4;
    protoMQ::BaseProperties base5;
    protoMQ::BaseProperties base6;
    protoMQ::BaseProperties base7;
    protoMQ::BaseProperties base8;
    protoMQ::BaseProperties base9;

    base1.set_id("2025-6-2---1"), base1.set_mode(protoMQ::DeliveryMode::durable), base1.set_routing_key(".111.0");
    base2.set_id("2025-6-2---2"), base2.set_mode(protoMQ::DeliveryMode::undurable), base2.set_routing_key(".111.0");

    base3.set_id("2025-6-2---3"), base3.set_mode(protoMQ::DeliveryMode::durable), base3.set_routing_key(".222.0");
    base4.set_id("2025-6-2---4"), base4.set_mode(protoMQ::DeliveryMode::undurable), base4.set_routing_key(".222.0");

    base5.set_id("2025-6-2---5"), base5.set_mode(protoMQ::DeliveryMode::durable), base5.set_routing_key(".111.0");
    base6.set_id("2025-6-2---6"), base6.set_mode(protoMQ::DeliveryMode::undurable), base6.set_routing_key(".111.0");

    base7.set_id("2025-6-2---7"), base7.set_mode(protoMQ::DeliveryMode::durable), base7.set_routing_key(".222.0");
    base8.set_id("2025-6-2---8"), base8.set_mode(protoMQ::DeliveryMode::undurable), base8.set_routing_key(".222.0");

    // 队列不存在情况测试
    hosts->insert("queue-100", &base1, "插入失败--queue100--持久化--.111.0", true);
    hosts->insert("queue-0", &base1, "插入成功--queue0--持久化--.111.0", true);

    // 持久化测试

    hosts->insert("queue-0", &base2, "插入成功--queue0--非持久化--.222.0", true);  // true但base为false
    hosts->insert("queue-0", &base3, "插入成功--queue0--非持久化--.111.0", false); // false但base为true
    hosts->insert("queue-0", &base5, "插入成功--queue0--持久化--.111.0", true);    // true且base为true
    hosts->insert("queue-0", &base4, "插入成功--queue0--非持久化--.222.0", false); // false且base为false

    hosts->insert("queue-0", nullptr, "插入成功--queue0--非持久化--空指针", false);
    hosts->insert("queue-0", nullptr, "插入成功--queue0--nullptr--持久化--空指针", true);

    // id重复情况--不使用unordered_map(因为unordered_map,导致加了3个, 文件层面有3个, 内存层面只有1个) ,我写的支持
    hosts->insert("queue-4", &base7, "测试消息1", true);
    LOG(logLevel::DEBUG) << "queue4内存消息数量:" << hosts->toBePushedSize("queue-4") << std::endl;
    hosts->insert("queue-4", &base7, "测试消息1", true);
    LOG(logLevel::DEBUG) << "queue4内存消息数量:" << hosts->toBePushedSize("queue-4") << std::endl;
    hosts->insert("queue-4", &base7, "测试消息1", true);
    LOG(logLevel::DEBUG) << "queue4内存消息数量:" << hosts->toBePushedSize("queue-4") << std::endl;

    hosts->insert("queue-5", nullptr, "插入成功--queue5--非持久化--空指针--first", false);
    hosts->insert("queue-5", nullptr, "插入成功--queue5--非持久化--空指针--two", false);
    hosts->insert("queue-5", nullptr, "插入成功--queue5--非持久化--空指针--three", false);
}

// 获取队首消息测试
TEST(MessageTest, front_test)
{
    std::cout << hosts->front("queue-5")->payload().data() << std::endl;
    std::cout << hosts->front("queue-5")->payload().data() << std::endl;
    std::cout << hosts->front("queue-5")->payload().data() << std::endl;
}

// 确认队列消息测试
TEST(MessageTest, ack_test)
{
    LOG(logLevel::DEBUG) << "待推送消息数量应为3, 实为:" << hosts->toBePushedSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "待确认消息数量应为0, 实为:" << hosts->waitackSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "持久化消息数量应为3, 实为:" << hosts->totalSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "有效持久化消息数量应为3, 实为:" << hosts->validSize("queue-4") << std::endl;

    std::cout << hosts->front("queue-4")->payload().data() << std::endl;
    std::cout << hosts->front("queue-4")->payload().data() << std::endl;
    std::cout << hosts->front("queue-4")->payload().data() << std::endl;

    LOG(logLevel::DEBUG) << "待推送消息数量应为0, 实为:" << hosts->toBePushedSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "待确认消息数量应为3, 实为:" << hosts->waitackSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "持久化消息数量应为3, 实为:" << hosts->totalSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "有效持久化消息数量应为3, 实为:" << hosts->validSize("queue-4") << std::endl;

    hosts->ack("queue-4", "2025-6-2---7");
    hosts->ack("queue-4", "2025-6-2---7");
    hosts->ack("queue-4", "2025-6-2---7");

    LOG(logLevel::DEBUG) << "待推送消息数量应为0, 实为:" << hosts->toBePushedSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "待确认消息数量应为0, 实为:" << hosts->waitackSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "持久化消息数量应为3, 实为:" << hosts->totalSize("queue-4") << std::endl;
    LOG(logLevel::DEBUG) << "有效持久化消息数量应为0, 实为:" << hosts->validSize("queue-4") << std::endl;
}

TEST(MessageTest, gc_test)
{
    for (int i = 0; i <= 10000; i++)

    {
        // 新增消息
        hosts->insert("queue-9", nullptr, "", true);

        // 获取消息
        auto ptr = hosts->front("queue-9");

        // 确认消息
        std::random_device rd;  // 获取随机种子
        std::mt19937 gen(rd()); // 使用 Mersenne Twister 引擎，初始化种子

        // 2. 定义随机数分布
        // 生成 [1, 100] 的整数
        std::uniform_int_distribution<int> int_dist(1, 100);

        // 3. 生成随机数
        int ran = int_dist(gen);
        if (ran % 2 == 0 || ran % 3 == 0)
        {
            if (!hosts->ack("queue-9", ptr->payload().properties().id()))
            {
                LOG(logLevel::WARNING) << "循环在" << i << "处异常中断!" << std::endl;
                break;
            }
        }

        // 每100次打印文件大小, 且条件满足 总:无效 约为40%时打印
        if (i % 200 == 0)
        {
            FileHelper fh("./queue-9.mqd");
            std::cout << "--------"<< std::endl;
            LOG(logLevel::DEBUG) << "当前文件大小:" << fh.size() << std::endl;
            LOG(logLevel::DEBUG) << "当前总持久化数量:" << hosts->totalSize("queue-9") << std::endl;
            LOG(logLevel::DEBUG) << "当前有效持久化数量:" << hosts->validSize("queue-9") << std::endl;
            std::cout << "--------"<< std::endl;
        }
    }
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new MessageTest);
    int ret = RUN_ALL_TESTS();
    return 0;
}